package com.zhouyu.mybatis.spring;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;

import java.util.Set;

/**
 * @author 周瑜
 */
public class ZhouyuBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {

	public ZhouyuBeanDefinitionScanner(BeanDefinitionRegistry registry) {
		super(registry);
	}

	@Override
	protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
		Set<BeanDefinitionHolder> beanDefinitionHolders = super.doScan(basePackages);

		for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
			BeanDefinition beanDefinition = beanDefinitionHolder.getBeanDefinition();

			//这里从bd中获取构造函数参数值列表，然后添加beanClassName当做构造函数的参数值，构造bean时，将使用对应的构造函数
			beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanDefinition.getBeanClassName());
			//将BeanClassName替换成FactoryBean 用户可以通过实现该接口定制实例化Bean的逻辑。可以隐藏实例化一些复杂Bean的细节
			beanDefinition.setBeanClassName(ZhouyuFactoryBean.class.getName());
			//mybatis中 beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); 可以自动注入setSqlSession
			//beanName没有改变，因此bdm中依然会有每个扫描到的每个bean的定义
		}

		return beanDefinitionHolders;
	}

	@Override
	protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
		return beanDefinition.getMetadata().isInterface();
	}
}
